// maps.js - Google Map code for iSpotter
//
// Copyright (C) 2008 Yuuichi Teranishi
//
// This file is derived from Stumbler, a program developed by iphone-wireless
// project.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// published by the Free Software Foundation.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; If not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

function zoomNumber (z) {
    return (19 - (z * 3));
}

function setZoom (zm) {
    map.setZoom(zoomNumber(zm));
}

function setFloor(f) {
    floor = f;
}

function currentLng() {
    var xy = map.getCenter();
    return xy.lng() + "";
}

function currentLat() {
    var xy = map.getCenter();
    return xy.lat() + "";
}

function currentFloor() {
    return floor + "";
}

function start(x, y, z) {
    tracking = true;
    zoom = zoomNumber(z);
    $("map").innerHTML = "";
    try {
	map = new GMap2(document.getElementById("map"));
    }
    catch (e) {
	$("map").innerHTML = "<BR><BR><BR><BR><BR><BR><center>map loading failure<BR>" + e + "</center>";
	window.webview.messageAreaExecJavaScript_("message('');");
    }
    map.setCenter(new GLatLng(y, x), zoom);
    //    map.addControl(new SelectableZoomControl());
    GEvent.addListener(map,"click", function(o,p) {
	    moveTo(p.lng(), p.lat(), null, true);
	});

    curView = "normal";
    icon = new GIcon();
    icon.image = "centerCross.gif";
    icon.iconSize = new GSize(30, 30);
    icon.iconAnchor = new GPoint(15,15);

//    lastX = null;
//    lastY = null;
//    lastF = null;

    trailIcon1 = new GIcon();
    trailIcon1.image = "trail1.png";
    trailIcon1.iconSize = new GSize(10, 10);
    trailIcon1.iconAnchor = new GPoint(5,5);

    trailIcon2 = new GIcon();
    trailIcon2.image = "trail2.png";
    trailIcon2.iconSize = new GSize(10, 10);
    trailIcon2.iconAnchor = new GPoint(5,5);

    trailIcon3 = new GIcon();
    trailIcon3.image = "trail3.png";
    trailIcon3.iconSize = new GSize(10, 10);
    trailIcon3.iconAnchor = new GPoint(5,5);

    marker = new GMarker(map.getCenter(), icon);
    map.addOverlay(marker);

    // handler = new MapSurfaceController(map);
    //    new ViewController(handler);
}

function detect() {
    window.webview.detect();
}

function changeView() {
    if (curView == "normal") {
	map.setMapType(G_SATELLITE_MAP);
	curView = "satellite";
    }
    else {
	map.setMapType(G_NORMAL_MAP);
	curView = "normal";
    }
}

function zoomIn() {
    map.zoomIn();
}

function zoomOut() {
    map.zoomOut();
}

function execute(url) {
    script = document.createElement ("script");
    script.setAttribute ("type", "text/javascript");
    script.setAttribute ("src", url);
    document.getElementById("json").appendChild(script);
}

function setLatest(x, y) {
    if (lastX != null && lastY != null && !(lastX == x && lastY == y)) {
	lastX = x;
	lastY = y;
    }
}

function clearTrails() {
    map.clearOverlays();
    marker = new GMarker(map.getCenter(), icon);
    map.addOverlay(marker);
}

function enableTracking(enable) {
    if (enable == 0) {
	tracking = false;
	window.webview.messageAreaExecJavaScript_("message('Tracking mode disabled');");
    }
    else {
	tracking = true;
	window.webview.messageAreaExecJavaScript_("message('Tracking mode enabled');");
    }
}

function staying() {
    if (lastX != null && lastY != null) {
	if (tracking) {
	    moveTo(lastX, lastY, lastF);
	}
    }
}

function dropTrail(x, y, f, p) {
    lastF = f;
    if (!(lastX == x && lastY == y)) {
	lastX = x;
	lastY = y;
	var icon;
	if (p == 1) {
	    icon = trailIcon1;
	}
	else if (p == 2) {
	    icon = trailIcon2;
	}
	else {
	    icon = trailIcon3;
	}
	map.addOverlay(new GMarker(new GLatLng(y, x), icon));
	// follow current position.
	if (tracking) {
	    moveTo(x, y, f);
	}
	//	message("Moved: " + new Date());
    }
    else {
	//	message("Staying: " + new Date());
    }
}

function gotoFloor(f) {
    floor = f;
    lastF = f;
    window.webview.gotoFloor_(f);
}

// bootstrap function.
function startWithTrails(trails, z){
    // Start with the last trail.
    if (trails !=null && trails.length > 0) {
	start(trails[trails.length - 1][1], trails[trails.length - 1][0], z);
	redrawTrails(trails);
    }
    else {
	// Default place...Osaka Univ...
	start(135.5265605, 34.822065, 12);
	window.webview.messageAreaExecJavaScript_("message('');");
    }
}

function startWithDate(date) {
    var script = document.createElement ("script");
    script.setAttribute ("type", "text/javascript");
    // localhost does not work offline
    script.setAttribute ("src", "http://127.0.0.1:5448/?c=logs&m=start&date=" + date + "&id=" + new Date());
    document.getElementById("json").appendChild(script);
}

function changeDate(date) {
    var script = document.createElement ("script");
    script.setAttribute ("type", "text/javascript");
    // localhost does not work offline
    script.setAttribute ("src", "http://127.0.0.1:5448/?c=logs&date=" + date + "&id=" + new Date());
    document.getElementById("json").appendChild(script);
}

function redrawTrails(trails){
    if (typeof(map) == "undefined") {
	$("map").innerHTML = "Load map failure";
	window.webview.messageAreaExecJavaScript_("message('no map available');");
    }
    else {
    map.clearOverlays();
    marker = new GMarker(map.getCenter(), icon);
    map.addOverlay(marker);
    var lastx, lasty;
    for (var i = 0; i < trails.length; i++) {
	var ticon;
	if (trails[i][2] == 1) {
	    ticon = trailIcon1;
	}
	else if (trails[i][2] == 2) {
	    ticon = trailIcon2;
	}
	else {
	    ticon = trailIcon3;
	}
	if ((lasty != trails[i][0]) &&
	    (lastx != trails[i][1])) {
	    map.addOverlay(new GMarker(new GLatLng(trails[i][0], trails[i][1]),
				       ticon));
	}
	lasty = trails[i][0];
	lastx = trails[i][1];
    }
    lastX = lastx;
    lastY = lasty;
    moveTo(lastX, lastY);
    window.webview.messageAreaExecJavaScript_("message('" + trails.length + " location(s)')");
    }
}

function setCenterPixel(x, y) {
    var newCenterLatLng = this.map.fromContainerPixelToLatLng(new GPoint(x, y));
    //    map.setCenter(newCenterLatLng);
    map.setCenter(newCenterLatLng);
    map.removeOverlay(marker);
    marker = new GMarker(newCenterLatLng, icon);
    map.addOverlay(marker);
}

function moveTo(x, y, f, smooth) {
    if (x != null && y != null) {
	if (smooth) {
	    map.panTo(new GLatLng(y, x));
	}
	else {
	    map.setCenter(new GLatLng(y, x));
	}
	if (f != null) gotoFloor(f);
	map.removeOverlay(marker);
	marker = new GMarker(new GLatLng(y, x), icon);
	map.addOverlay(marker);
	//document.getElementById("geometry").innerHTML = "(" + x + "," + y + ")";
    }
}

function functify(object, func) {
    return function() {
	func.apply(object, arguments);
    };
}

function showPromptGlass() {
    $("promptGlass").style.display = "block";
}

function hidePromptGlass() {
    $("promptGlass").style.display = "none";
}

function $(id) {
    return document.getElementById(id);
}

function MapSurfaceController(map) {
    this.map = map;

    this.surface = $("surface");
    this.mapContainer = $("map");
}

MapSurfaceController.prototype.zoomIn = function() {
    this.recenterMap();
    this.map.zoomIn();
};

MapSurfaceController.prototype.zoomOut = function() {
    this.recenterMap();
    this.map.zoomOut();
};

// From 'Google Maps on iPod touch'... not used
MapSurfaceController.prototype.resetScrollPosition = function() {
    var scrollerHeight = this.surface.offsetHeight;
    var scrollerWidth = this.surface.offsetWidth;
    var mapHeight = this.mapContainer.offsetHeight;
    var mapWidth = this.mapContainer.offsetWidth;

    var desiredScrollTop = (mapHeight / 2) - (scrollerHeight / 2);
    if (desiredScrollTop != this.surface.scrollTop) {
	this.scrollEventsToIgnore++;
	this.surface.scrollTop = desiredScrollTop;
    }

    var desiredScrollLeft = (mapWidth / 2) - (scrollerWidth / 2);
    if (desiredScrollLeft != this.surface.scrollLeft) {
	this.scrollEventsToIgnore++;
	this.surface.scrollLeft = desiredScrollLeft;
    }
};

MapSurfaceController.prototype.onScroll = function(event) {
    if (this.scrollEventsToIgnore > 0) {
	this.scrollEventsToIgnore--;
	return true;
    }

    var scrollTop = this.surface.scrollTop;
    var scrollLeft = this.surface.scrollLeft;
    var surfaceHeight = this.surface.offsetHeight;
    var surfaceWidth = this.surface.offsetWidth;
    var scrollRight = scrollLeft + surfaceWidth;
    var scrollBottom = scrollTop + surfaceHeight;
    var mapWidth = this.mapContainer.offsetWidth;
    var mapHeight = this.mapContainer.offsetHeight;

    if (scrollTop > 0 && scrollLeft > 0 &&
	 scrollRight < mapWidth && scrollBottom < mapHeight) {
	 return true;
     }
    this.recenterMap();
    return true;
};

MapSurfaceController.prototype.recenterMap = function() {
    var scrollLeft = this.surface.scrollLeft;
    var surfaceWidth = this.surface.offsetWidth;
    var scrollTop = this.surface.scrollTop;
    var surfaceHeight = this.surface.offsetHeight;

    var curPixelCenter = new GPoint(scrollLeft + surfaceWidth/2,
				    scrollTop + surfaceHeight/2);
    var newCenterLatLng = this.map.fromContainerPixelToLatLng(curPixelCenter);
    this.setMapCenter(newCenterLatLng);
};

MapSurfaceController.prototype.panMapTo = function(latlng) {
    this.map.panTo(latlng);
    this.resetScrollPosition();
};

MapSurfaceController.prototype.setMapCenter = function(latlng) {
    this.map.setCenter(latlng);
    this.resetScrollPosition();
};

function ViewController(mapController) {
    this.mapController = mapController;
    $("zoomInButton").onclick = functify(this, this.zoomIn);
    $("zoomOutButton").onclick = functify(this, this.zoomOut);
}

ViewController.prototype.zoomIn = function() {
    this.mapController.zoomIn();
};

ViewController.prototype.zoomOut = function() {
    this.mapController.zoomOut();
};

function SelectableZoomControl () {
}

SelectableZoomControl.prototype = new GControl ();

SelectableZoomControl.prototype.initialize = function(map) {
  var container = document.createElement("div");

  var div = document.createElement("div");
  container.appendChild(div);

//   var zoomInDiv = document.createElement("div");
//   this.setButtonStyle_(zoomInDiv);
//   container.appendChild(zoomInDiv);
//   zoomInDiv.appendChild(document.createTextNode("Zoom In"));
//   GEvent.addDomListener(zoomInDiv, "click", function() {
//     map.zoomIn();
//   });

//   var zoomOutDiv = document.createElement("div");
//   this.setButtonStyle_(zoomOutDiv);
//   container.appendChild(zoomOutDiv);
//   zoomOutDiv.appendChild(document.createTextNode("Zoom Out"));
//   GEvent.addDomListener(zoomOutDiv, "click", function() {
//     map.zoomOut();
//   });

  map.getContainer().appendChild(container);
  return container;
}

SelectableZoomControl.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 7));
}

